package com.weixin.core;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.weixin.config.WxConfig;
import com.weixin.interfaces.WeixinToken;
import com.weixin.utils.WxHttp;
import com.weixin.utils.WxJson;

/** 
 * 类描述：获取微信token<br>
 * 创建人：邓强   <br>
 * 创建时间：2017年10月27日 下午4:29:43    <br> 
 * 修改人：  <br>
 * 修改时间：2017年10月27日 下午4:29:43   <br>  
 * 修改备注：     <br>
 * @version   V1.0      
 */
@SuppressWarnings("unchecked")
public class TokenFactory {
	private static Logger log=LoggerFactory.getLogger(TokenFactory.class);
	
	private static Map<String, WxConfig> wxConfigs = new HashMap<>();
	
	private static WxConfig defaultWxConfig = null;
	
	private static WeixinToken weixinToken = null;
	private static WeixinToken weixinJsToken = null;
	
	public static void initial(String wxNo, String appId,String appsecret){
		initial(wxNo, appId, appsecret, new DefaultWxToken(),new DefaultWxJsToken());
	}
	
	public static void initial(String wxNo, String appId,String appsecret,WeixinToken weixinToken){
		initial(wxNo, appId, appsecret, weixinToken,new DefaultWxJsToken());
	}
	
	public static void initial(String wxNo, String appId,String appsecret,WeixinToken weixinToken,WeixinToken weixinJsToken){
		WxConfig wxConfig = new WxConfig();
    	wxConfig.setWxNo(wxNo);
    	wxConfig.setAppId(appId);
    	wxConfig.setAppsecret(appsecret);
    	TokenFactory.weixinToken = weixinToken;
    	TokenFactory.weixinJsToken = weixinJsToken;
    	TokenFactory.addWxConfigs(wxConfig);
	}
	public static void addWxConfigs(String wxNo, String appId,String appsecret){
		WxConfig wxConfig = new WxConfig();
    	wxConfig.setWxNo(wxNo);
    	wxConfig.setAppId(appId);
    	wxConfig.setAppsecret(appsecret);
    	addWxConfigs(wxConfig);
	}
	
	public static void addWxConfigs(WxConfig wxConfig){
		if(wxConfigs.size() == 0){
			defaultWxConfig = wxConfig;
		}
		
		wxConfigs.put(wxConfig.getWxNo(), wxConfig);
		
		if(TokenFactory.weixinToken == null){
			initialWeixinToken(new DefaultWxToken());
	    	
		}
		if(TokenFactory.weixinJsToken == null){
			initialWeixinJsToken(new DefaultWxJsToken());
		}
	}
	
	public static void addAllWxConfigs(Map<String, WxConfig> configs){
		if(wxConfigs.size() == 0){
			Iterator<WxConfig> it = configs.values().iterator();
			if (it.hasNext()) {
				WxConfig wxConfig = it.next();
				defaultWxConfig = wxConfig;
			}
		}
		wxConfigs.putAll(configs);
		
		if(TokenFactory.weixinToken == null){
			initialWeixinToken(new DefaultWxToken());
	    	
		}
		if(TokenFactory.weixinJsToken == null){
			initialWeixinJsToken(new DefaultWxJsToken());
		}
	}
	
	
	public static void initialWeixinToken(WeixinToken weixinToken){
			TokenFactory.weixinToken = weixinToken;
	}
	
	public static void initialWeixinJsToken(WeixinToken weixinJsToken){
			TokenFactory.weixinJsToken = new DefaultWxJsToken();
	}

	public static WxConfig getDefaultWxConfigs() {
		return defaultWxConfig;
	}
	
	/**
	 * 设置默认公众号<br>
	 * <br>  
	 * 创建人：邓强   <br>
	 * 创建时间：2017年10月31日 下午1:43:43    <br> 
	 * 修改人：  <br>
	 * 修改时间：2017年10月31日 下午1:43:43   <br>  
	 * 修改备注：     <br> 
	 * @param wx_no
	 */
	public static void setDefaultWxConfigs(String wx_no) {
		WxConfig wxConfig = getWxConfig(wx_no);
		if(wxConfig != null ){
			TokenFactory.defaultWxConfig = wxConfig;
		}
	}

	public static void setDefaultWxConfigs(WxConfig defaultWxConfigs) {
		TokenFactory.defaultWxConfig = defaultWxConfigs;
	}

	public static String getToken() {
		if (defaultWxConfig != null) {
			return getToken(defaultWxConfig);
		}else{
		throw new RuntimeException("没有初始化微信配置");
		}
	}
	
	public static String getToken(WxConfig wxConfig) {
		String token = weixinToken.getToken(wxConfig.getWxNo());
		if(StringUtils.isBlank(token)){
			token = getAccessToken(wxConfig);
			weixinToken.saveToken(wxConfig.getWxNo(), token);
		}
		return token;
	}
	
	public static boolean saveToken(String wxNo,String token){
		return weixinToken.saveToken(wxNo, token);
	}

	public static boolean deleteToken(WxConfig wxConfig) {
		return weixinToken.deleteToken(wxConfig.getWxNo());
	}
	
	public static String getJsToken() {
		if (defaultWxConfig != null) {
			return getJsToken(defaultWxConfig);
		}else{
			throw new RuntimeException("没有初始化微信配置");
		}
	}
	
	public static String getJsToken(WxConfig wxConfig) {
		String jsToken = weixinJsToken.getToken(wxConfig.getWxNo());
		if(StringUtils.isBlank(jsToken)){
			jsToken = getAccessJsToken(wxConfig);
			weixinJsToken.saveToken(wxConfig.getWxNo(), jsToken);
		}
		return jsToken;
	}

	public static boolean deleteJsToken(WxConfig wxConfig) {
		return weixinJsToken.deleteToken(wxConfig.getWxNo());
	}
	
	
	
	public static WxConfig getWxConfig(String wx_no) {
		return wxConfigs.get(wx_no);
	}

	/**
	 * @Description:第三方公众号获取Token的方法<br/> 
	 * @param wxAccountId
	 * @param appId
	 * @param appSecret
	 * @return
	 * @author 邓强
	 * @date 2017年1月17日 下午3:47:01
	 */
	private static String getAccessToken(WxConfig wxConfig) {
		String accessToken = null;
			try{
				String requestUrl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+wxConfig.getAppId()+"&secret="+wxConfig.getAppsecret();
				String resStr=WxHttp.httpsRequest(requestUrl,null);
				Map<String, Object> mapJson=WxJson.fromJson(resStr, Map.class);
				if(mapJson!=null && mapJson.get("access_token")!=null){
					accessToken=(String)mapJson.get("access_token");
					log.info("获取token成功：{}", accessToken);
				}else {
					log.error("获取token失败,公众号:{}-----------{}",wxConfig.getWxNo(), mapJson);
				}
			} catch (Exception e) {
				log.error("获取微信token异常,公众号公众号:{}",wxConfig.getWxNo(), e);
			}
		return accessToken;
	}
	
	/**
	 * 获取accessToken
	 * @return
	 */
	private static String getAccessJsToken(WxConfig wxConfig){
		String ticket = null;
		try{
			String requestUrl="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+getToken(wxConfig)+"&type=jsapi";
			String resStr=WxHttp.httpsRequest(requestUrl,null);
			Map<String, Object> mapJson=WxJson.fromJson(resStr, Map.class);
			if(mapJson!=null && mapJson.get("ticket")!=null){
				ticket=(String)mapJson.get("ticket");
				log.info("获取js_ticket成功："+ticket);
			}else {
				log.error("获取js_ticket失败,"+mapJson);
			}
		} catch (Exception e) {
			log.error("获取微信js_ticket异常", e);
		}
		return ticket;
	}

}
